home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / linux / spi / spi_bitbang.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  4.3 KB  |  147 lines

  1. #ifndef    __SPI_BITBANG_H
  2. #define    __SPI_BITBANG_H
  3.  
  4. /*
  5.  * Mix this utility code with some glue code to get one of several types of
  6.  * simple SPI master driver.  Two do polled word-at-a-time I/O:
  7.  *
  8.  *   -    GPIO/parport bitbangers.  Provide chipselect() and txrx_word[](),
  9.  *    expanding the per-word routines from the inline templates below.
  10.  *
  11.  *   -    Drivers for controllers resembling bare shift registers.  Provide
  12.  *    chipselect() and txrx_word[](), with custom setup()/cleanup() methods
  13.  *    that use your controller's clock and chipselect registers.
  14.  *
  15.  * Some hardware works well with requests at spi_transfer scope:
  16.  *
  17.  *   -    Drivers leveraging smarter hardware, with fifos or DMA; or for half
  18.  *    duplex (MicroWire) controllers.  Provide chipslect() and txrx_bufs(),
  19.  *    and custom setup()/cleanup() methods.
  20.  */
  21.  
  22. #include <linux/workqueue.h>
  23.  
  24. struct spi_bitbang {
  25.     struct workqueue_struct    *workqueue;
  26.     struct work_struct    work;
  27.  
  28.     spinlock_t        lock;
  29.     struct list_head    queue;
  30.     u8            busy;
  31.     u8            use_dma;
  32.     u8            flags;        /* extra spi->mode support */
  33.  
  34.     struct spi_master    *master;
  35.  
  36.     /* setup_transfer() changes clock and/or wordsize to match settings
  37.      * for this transfer; zeroes restore defaults from spi_device.
  38.      */
  39.     int    (*setup_transfer)(struct spi_device *spi,
  40.             struct spi_transfer *t);
  41.  
  42.     void    (*chipselect)(struct spi_device *spi, int is_on);
  43. #define    BITBANG_CS_ACTIVE    1    /* normally nCS, active low */
  44. #define    BITBANG_CS_INACTIVE    0
  45.  
  46.     /* txrx_bufs() may handle dma mapping for transfers that don't
  47.      * already have one (transfer.{tx,rx}_dma is zero), or use PIO
  48.      */
  49.     int    (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);
  50.  
  51.     /* txrx_word[SPI_MODE_*]() just looks like a shift register */
  52.     u32    (*txrx_word[4])(struct spi_device *spi,
  53.             unsigned nsecs,
  54.             u32 word, u8 bits);
  55. };
  56.  
  57. /* you can call these default bitbang->master methods from your custom
  58.  * methods, if you like.
  59.  */
  60. extern int spi_bitbang_setup(struct spi_device *spi);
  61. extern void spi_bitbang_cleanup(struct spi_device *spi);
  62. extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m);
  63. extern int spi_bitbang_setup_transfer(struct spi_device *spi,
  64.                       struct spi_transfer *t);
  65.  
  66. /* start or stop queue processing */
  67. extern int spi_bitbang_start(struct spi_bitbang *spi);
  68. extern int spi_bitbang_stop(struct spi_bitbang *spi);
  69.  
  70. #endif    /* __SPI_BITBANG_H */
  71.  
  72. /*-------------------------------------------------------------------------*/
  73.  
  74. #ifdef    EXPAND_BITBANG_TXRX
  75.  
  76. /*
  77.  * The code that knows what GPIO pins do what should have declared four
  78.  * functions, ideally as inlines, before #defining EXPAND_BITBANG_TXRX
  79.  * and including this header:
  80.  *
  81.  *  void setsck(struct spi_device *, int is_on);
  82.  *  void setmosi(struct spi_device *, int is_on);
  83.  *  int getmiso(struct spi_device *);
  84.  *  void spidelay(unsigned);
  85.  *
  86.  * A non-inlined routine would call bitbang_txrx_*() routines.  The
  87.  * main loop could easily compile down to a handful of instructions,
  88.  * especially if the delay is a NOP (to run at peak speed).
  89.  *
  90.  * Since this is software, the timings may not be exactly what your board's
  91.  * chips need ... there may be several reasons you'd need to tweak timings
  92.  * in these routines, not just make to make it faster or slower to match a
  93.  * particular CPU clock rate.
  94.  */
  95.  
  96. static inline u32
  97. bitbang_txrx_be_cpha0(struct spi_device *spi,
  98.         unsigned nsecs, unsigned cpol,
  99.         u32 word, u8 bits)
  100. {
  101.     /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */
  102.  
  103.     /* clock starts at inactive polarity */
  104.     for (word <<= (32 - bits); likely(bits); bits--) {
  105.  
  106.         /* setup MSB (to slave) on trailing edge */
  107.         setmosi(spi, word & (1 << 31));
  108.         spidelay(nsecs);    /* T(setup) */
  109.  
  110.         setsck(spi, !cpol);
  111.         spidelay(nsecs);
  112.  
  113.         /* sample MSB (from slave) on leading edge */
  114.         word <<= 1;
  115.         word |= getmiso(spi);
  116.         setsck(spi, cpol);
  117.     }
  118.     return word;
  119. }
  120.  
  121. static inline u32
  122. bitbang_txrx_be_cpha1(struct spi_device *spi,
  123.         unsigned nsecs, unsigned cpol,
  124.         u32 word, u8 bits)
  125. {
  126.     /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */
  127.  
  128.     /* clock starts at inactive polarity */
  129.     for (word <<= (32 - bits); likely(bits); bits--) {
  130.  
  131.         /* setup MSB (to slave) on leading edge */
  132.         setsck(spi, !cpol);
  133.         setmosi(spi, word & (1 << 31));
  134.         spidelay(nsecs); /* T(setup) */
  135.  
  136.         setsck(spi, cpol);
  137.         spidelay(nsecs);
  138.  
  139.         /* sample MSB (from slave) on trailing edge */
  140.         word <<= 1;
  141.         word |= getmiso(spi);
  142.     }
  143.     return word;
  144. }
  145.  
  146. #endif    /* EXPAND_BITBANG_TXRX */
  147.